/**
 * @file DynamicArray.h
 * @author Stephen Smith
 *
 * @brief Functions to manipulate dynamic arrays
 * @section Description
 *
 * Functions to manipulate dynamic arrays.
 *
 * In these dynamic arrays, the elements are not copied: pointers to
 * them are. If you wish to store a copy of something, you must copy
 * it yourself. Storing things allocated on the stack is also likely
 * to cause problems.
 *
 * These arrays are zero-indexed.
 */

#ifndef DYNAMIC_ARRAY_HEADER
#define DYNAMIC_ARRAY_HEADER

#include <stdlib.h>
#include <string.h>
#include <errno.h>

/**
 * @brief A dynamic array.
 *
 * Represents a dynamic array. Note that this type is a pointer.
 */
typedef struct dynarray
{

  void **array ; /**< The array itself */
  unsigned int length ; /**< The length of the array (in elements) */
  unsigned int max_length ; /**< The maximum length the array has been
			       (in elements) */

} *D_Array ;

/** 
 * Make a new dynamic array
 *
 * @param len initial length of the array
 *
 * @return the new array
 */
D_Array NewArray( unsigned int len ) ;

/**
 * Free a dynamic array. Note that this does not free the elements of
 * the array.
 *
 * @param array the array to free
 *
 * @return always 0, until free(3) decides to report errors, rather
 * than die in flames
 */
int FreeArray( D_Array array ) ;

/**
 * Append an element to a dynamic array.
 * @param array the array to operate on
 * @param element a pointer to the element to append
 *
 * @return 0 on success, -errno on failure
 */
int AppendElement( D_Array array , void *element ) ;

/**
 * Insert an element to a dynamic array.
 *
 * @param array the array to operate on
 * @param n the position to insert the element
 * @param element a pointer to the element to append
 *
 * @return 0 on success, -errno on failure
 */
int InsertElement( D_Array array , unsigned int n , void *element ) ;

/**
 * Remove an element from a dynamic array
 *
 * @param array the array to operate on
 * @param n the index of the element to remove
 *
 * @return 0 on success, -errno on failure
 */
int RemoveElement( D_Array array , unsigned int n ) ;

/**
 * Set an element of a dynamic array to a supplied value.
 *
 * @param array the array to operate on
 * @param n the position of the element to set
 * @param element a pointer to the element to set
 *
 * @return 0 on success, -errno on failure
 */
int SetElement( D_Array array , unsigned int n , void *element ) ;

/**
 * Return an element of a dynamic array
 *
 * @param array the array to operate on
 * @param n the index of the element to return
 *
 * @return a pointer to the element asked for, or NULL if it doesn't
 * exist (e.g. if the element asked for is beyond the end of the array 
 */
void *GetElement( D_Array array , unsigned int n ) ;

/**
 * Return the length of a dynamic array
 *
 * @param array the array to find the length of
 *
 * @return the length of the array
 */
unsigned int GetLength( D_Array array ) ;

#endif
